package com.zys.sac.core.filter;

import com.zys.sac.core.constant.RequestParam;
import com.zys.sac.core.constant.RequestStatus;
import com.zys.sac.core.helper.TokenManager;
import com.zys.sac.core.util.ServletResponseUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 自定义jwt token校验过滤器，用来替换Security原来的用户名密码过滤器
 *
 * Created by zhongjunkai on 2022/3/8.
 */
@Slf4j
public class JwtCheckFilter extends SacCheckFilter {

    protected String loginPath;

    @Autowired
    private TokenManager tokenManager;

    public JwtCheckFilter(String loginPath) {
        this.loginPath = loginPath;
    }

    @Override
    public String loginPath() {
        return this.loginPath;
    }

    @Override
    protected boolean doCheck(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String token = request.getHeader(RequestParam.TOKEN);
        if (!StringUtils.hasText(token)) {
            ServletResponseUtils.render(response, ServletResponseUtils.result(RequestStatus.TOKENEMPTY.getCode(), RequestStatus.TOKENEMPTY.getMsg()));
        }
        UserDetails userDetails;
        try {
            userDetails = (UserDetails) tokenManager.getUserDetails(token);
        } catch (Exception e) {
            log.error("获取缓存用户信息发生异常{}", e);
            ServletResponseUtils.render(response, ServletResponseUtils.result(RequestStatus.INVALIDTOKEN.getCode(), RequestStatus.INVALIDTOKEN.getMsg()));
            return false;
        }
        if (userDetails == null) {
            ServletResponseUtils.render(response, ServletResponseUtils.result(RequestStatus.INVALIDTOKEN.getCode(), RequestStatus.INVALIDTOKEN.getMsg()));
            return false;
        }
        // 更新缓存的有效期
        tokenManager.renewalToken(token);
        // 这里将权限和角色交给权限交给SpringSecurity容器进行管理，后续的SpringSecurity验证过滤器会自动对权限进行过滤，无需自己手动过滤
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
        return true;
    }
}
